<h1>{{ params.title ?? "Default Title" }}</h1>

{% set dataConfiguration = params.dashboardConfiguration.data %}
{% set gridConfiguration = params.dashboardConfiguration.grid %}

<script>
  const dataConfiguration = {{ dataConfiguration|json_encode|raw }};
</script>

<style>
  .draggable-hover {
    border: 3px dashed #c7c7c7;
    border-radius: 10px;
    text-align: center;
    padding: 30px;
    margin: 20px;
  }

  .draggable-hover:after {
    content: "Drop here";
  }

  .hidden-temp {
    display: none !important;
  }

  .hidden {
    display: none !important;
  }

  .hidden-sufficient {
    display: none !important;
  }
</style>

<ul class="pagination ml-3">
  {% for preset in params.availablePresets %}
    <li class="page-item {% if params.preset == preset %} active {% endif %}">
      <a class="page-link" href="?preset={{ preset }}">{{ preset + 1 }}</a>
    </li>
  {% endfor %}

  <li class="page-item">
    <a class="page-link" href="?preset={{ params.availablePresets|length }}"><i class="fas fa-plus"></i> Add</a>
  </li>
</ul>

<div
  style="display: grid; grid-template-rows: auto; grid-template-areas: '{{ gridConfiguration|join("' '")|raw }}'; grid-gap: 10px;"
>
  {% for areaIndex, area in dataConfiguration %}
    <div class="card card-body m-3 p-0" style="grid-area: {{ area.key }};">
      <div id="draggableContainer-{{ area.key }}">
        {% for cardKey, card in area.cards %}
          <div 
            class="draggable"
            id="card_{{ card.action|replace({"/": "-"}) }}_{{ area.key }}_{{ cardKey }}"
            style="z-index: 100;"
          >
            <div 
              class="px-3 py-2 text-primary bg-light font-weight-bold d-flex justify-content-between"
              style="border-bottom: 1px solid #e3e6f0;"
            >
              <div class="">
                {{ card.params.title }}
              </div>
              <div>
                <button 
                  type="button" class="close text-danger" 
                  aria-label="Close"
                  onclick="deleteCard('card_{{ card.action|replace({"/": "-"}) }}_{{ area.key }}_{{ cardKey }}')"
                >
                  <span aria-hidden="true">&times;</span>
                </button>
              </div>
            </div>
            <div id="card_{{ card.action|replace({"/": "-"}) }}_{{ area.key }}_{{ cardKey }}_body"
              class="border border-light rounded-bottom bg-white" style="cursor: pointer;">
            </div>
          </div>
          <script>
            params = {{ card['params']|json_encode|raw }};

            _ajax_update(
              '{{ card['action'] }}',
              params,
              'card_{{ card.action|replace({"/": "-"}) }}_{{ area.key }}_{{ cardKey }}_body'
            )
          </script>
        {% endfor %}
      </div>
      <div
        class="dropdown d-flex justify-content-center align-items-center {% if area.cards|length != 0 %} hidden {% endif %}"
        id="addCards-{{ area.key }}"
        {% if params.availableCards|length == 0 %} disabled {% endif %}
      >
        <button 
          class="btn btn-primary dropdown-toggle m-5" 
          type="button" 
          id="dropdownMenuButton"
          data-toggle="dropdown"
          aria-haspopup="true" aria-expanded="false"
        >
          Add new card
        </button>
        <div class="dropdown-menu text-center" aria-labelledby="dropdownMenuButton">
          {% if params.availableCards|length == 0 %}
            {{ translate('Nothing available') }}
          {% endif %}

          {% for card in params.availableCards %}
            <button class="dropdown-item" onclick="addCard('{{ card.action }}', '{{ area.key }}')">
              {% if card.params.title %} {{ card.params.title }} {% else %} {{ card.action }} {% endif %}
            </button>
          {% endfor %}
        </div>
      </div>
    </div>
  {% endfor %}
</div>

<script>
  function getCardAction (cardId) {
    return cardId.split('_')[1].replaceAll('-', '/')
  }

  function pushToIndex (array, item, index) {
    array.splice(index, 0, item)

    for (let i = index + 1; i < array.length; i++) {
      array.splice(i, 0, array.splice(i, 1)[0])
    }
  }

  function updateSettings (reload = false) {
    const config = {{ params.dashboardConfiguration|json_encode|raw }}
      config.data = dataConfiguration

    _ajax_read(
      "{{ params.saveAction }}",
      {
        configuration: config,
        preset: {{ params.preset }}
      },
      (res) => {
        if (isNaN(res)) {
          alert(res)
        } else if (reload === true) {
          location.reload()
        }
      }
    )
  }

  function addCard (card, area) {
    _ajax_read(
      "{{ params.addCardsAction }}",
      {
        cards: JSON.stringify([card]),
        preset: {{ params.preset }},
        area: area
      },
      (res) => {
        if (isNaN(res)) {
          alert(res)
        } else {
          location.reload()
        }
      }
    )
  }

  function deleteCard (cardId) {
    const cardAction = getCardAction(cardId)

    dataConfiguration.forEach((area, areaIndex) => {
      dataConfiguration[areaIndex]['cards'] = dataConfiguration[areaIndex]['cards'].filter(
        item => item.action !== cardAction
      )
    })

    document.getElementById(cardId).remove()

    updateSettings(true)
  }

  function toggleDroppables (draggable, dropdowns) {
    draggable.forEach((item) => {
      const areaIndex = item.id.split('-')[1].charCodeAt(0) - 65
      const area = dataConfiguration[areaIndex]

      if (area.cards.length === 0) {
        item.classList.toggle('draggable-hover')
      }
    })

    dropdowns.forEach((item) => {
      item.classList.toggle('hidden-temp')
    })
  }

  const draggableContainers = [
    {% for areaIndex, area in dataConfiguration %}
    document.getElementById('draggableContainer-{{ area.key }}'),
    {% endfor %}
  ]

  const addCardDropdowns = [
    {% if params.availableCards|length != 0 %}
    {% for areaIndex, area in dataConfiguration %}
    document.getElementById('addCards-{{ area.key }}'),
    {% endfor %}
    {% endif %}
  ]

  const deletedCards = {}

  const draggableSortable = new Draggable.Sortable(draggableContainers, {
    draggable: `.draggable`,
    mirror: {
      constrainDimensions: true,
    },
    plugins: [],
  })

  draggableSortable.on('drag:start', (e) => {
    const originColumnIndex = e.sourceContainer.id.toString().split('-')[1].charCodeAt(0) - 65
    const cardId = e.data.originalSource.id
    const cardAction = getCardAction(cardId)
    const areaCards = dataConfiguration[originColumnIndex]['cards']

    deletedCards[cardId] = areaCards.find(item => item.action === cardAction)

    dataConfiguration[originColumnIndex]['cards'] = areaCards.filter(item => {
      return item.action !== cardAction
    })

    if (dataConfiguration[originColumnIndex]['cards'].length === 0) {
      document.getElementById('addCards-' + e.sourceContainer.id.toString().split('-')[1]).classList.toggle('hidden')
    }

    toggleDroppables(draggableContainers, addCardDropdowns)
  })

  draggableSortable.on('sortable:sort', (e) => {
    const targetColumnIndex = e.dragEvent.data.overContainer.id.toString().split('-')[1].charCodeAt(0) - 65
    if (dataConfiguration[targetColumnIndex].cards.length !== 0) {
      e.cancel()
    }
  })

  draggableSortable.on('sortable:stop', (e) => {
    toggleDroppables(draggableContainers, addCardDropdowns)
    const targetColumnIndex = e.newContainer.id.toString().split('-')[1].charCodeAt(0) - 65
    const cardId = e.data.dragEvent.data.originalSource.id

    pushToIndex(dataConfiguration[targetColumnIndex]['cards'], deletedCards[cardId], e.newIndex)

    if (dataConfiguration[targetColumnIndex]['cards'].length === 1) {
      document.getElementById('addCards-' + e.newContainer.id.toString().split('-')[1]).classList.toggle('hidden')
    }
    updateSettings()
  })
</script>

